#ifndef __E2E_H__
#define __E2E_H__

#include "common.h"

/* At least 8 bit*/
typedef unsigned long uint8_least;
typedef uint8 Std_ReturnType;
/**
 * brief Status type for E2E State Machine return values.
 */
typedef uint8 E2E_PCheckStatusType;

/**
 * brief State of the sender for a Data protected with E2E Profile 1.
 */
typedef struct {
  uint8 Counter;
  /**< Counter to be used for protecting the Data. The counter is incremented
   * modulo 15 */
} E2E_P01SenderStateType;
typedef E2E_P01SenderStateType E2E_P01ProtectStateType;

/**
 * brief Definition of E2E Profile 1 receiver status type.
 *
 * Result of the verification of the Data in E2E Profile 1, determined by the
 * Check function.
 */
typedef enum {
  E2E_P01STATUS_OK = 0x0U,
  /**< New data has been correctly received. */
  E2E_P01STATUS_NONEWDATA = 0x1U,
  /**< The Check function has been invoked but new Data is not available since
     the last call. */
  E2E_P01STATUS_WRONGCRC = 0x2U,
  /**< The data has been received according to communication medium, but the CRC
     is incorrect. */
  E2E_P01STATUS_SYNC = 0x3U,
  /**< New data has been received after detection of an unexpected behavior of
     counter. */
  E2E_P01STATUS_INITIAL = 0x4U,
  /**< New data has been correctly received, but this is the first Data since
   * the receiver's (re-)initialization. */
  E2E_P01STATUS_REPEATED = 0x8U,
  /**< New data has been correctly received, but the Counter is identical
   * to the most recent Data */
  /**< received with Status _INITIAL, _OK, or _OKSOMELOST. */
  E2E_P01STATUS_OKSOMELOST = 0x20U,
  /**< New data has been correctly received, but some data in the sequence
   * have been probably lost. */
  E2E_P01STATUS_WRONGSEQUENCE = 0x40U,
  /**< The new data has been correctly received, but the Counter Delta is too
   * big (DeltaCounter > MaxDeltaCounter) */
  E2E_P01STATUS_DATAINVALID = 0x80U
  /**< All bits in the received data except for byte 0 (CRC) are set to one. */
} E2E_P01ReceiverStatusType;
/**
 * brief Definition of E2E Profile 1 receiver state type.
 *
 * State of the sender for a Data protected with E2E Profile 1.
 */
typedef struct {
  E2E_P01ReceiverStatusType Status;
  /**< Result of the verification of the Data, determined by the Check function.
   */
  uint8 LastValidCounter;
  /**< Counter of last valid received message. */
  uint8 MaxDeltaCounter;
  /**< MaxDeltaCounter specifies the maximum allowed difference between two
   * counter values of */
  /**< consecutively received valid messages. */
  boolean WaitForFirstData;
  /**< If true means that no correct data (with correct Data ID and CRC) has
   * been yet received */
  /**< after the receiver (re-)initialization. */
  boolean NewDataAvailable;
  /**< Indicates to E2E Library that a new data is available for the Library to
   * be checked. */
  /**< This attribute is set by the E2E Library caller and not by the E2E
   * Library. */
  uint8 LostData;
  /**< Number of data (messages) lost since reception of last valid one. */
  uint8 NoNewOrRepeatedDataCounter;
  /**< Amount of consecutive reception cycles in which either (1) there was no
   * new data, or (2) when the data was repeated. */
  uint8 SyncCounter;
  /**< Number of consecutively received valid Data required for determining the
   * consistency of the counter. */
} E2E_P01ReceiverStateType;
/**
 * brief Definition of E2E Profile 1 check state type.
 *
 * Type-definition for backward-compatibility due to type renaming done in
 * AUTOSAR version 4.2.1.
 *
 */
typedef E2E_P01ReceiverStateType E2E_P01CheckStateType;
typedef E2E_P01ReceiverStatusType E2E_P01CheckStatusType;

/*==================[type definitions]=======================================*/
/**
 * brief Inclusion modes of Data ID for E2E Profile 1.
 *
 * The Data ID is two bytes long in E2E Profile 1. There are three inclusion
 * modes how the implicit two-byte Data ID is included in the one-byte CRC.
 */
/* CheckC disabled. E2E_P01DataIDMode must not be renamed to be consistent with
 * E2E Library spec */
/* CHECK: RULE 505 OFF */
typedef enum {
  E2E_P01_DATAID_BOTH = 0U,
  /**< Two bytes are included in the CRC .*/
  E2E_P01_DATAID_ALT = 1U,
  /**< One of the two bytes is included, alternating high and low byte. */
  E2E_P01_DATAID_LOW = 2U,
  /**< Only low byte is included, high byte is never used. */
  E2E_P01_DATAID_NIBBLE = 3U
  /**< The low byte is included in the implicit CRC calculation,
       the low nibble of the high byte is explicitly transmitted along with
       the data, the high nibble of the high byte is not used. */
} E2E_P01DataIDMode;
/**
 * brief Configuration of transmitted Data for E2E Profile 1.
 *
 * Configuration of transmitted Data (Data Element or I-PDU), for E2E Profile 1.
 * For each transmitted Data, there is an instance of this typedef.
 */
typedef struct {
  uint16 CounterOffset;
  /**< Bit offset of Counter (Least Significant Bit) from the beginning of the
   * Byte-Array (bit numbering: bit 0 is the least important). The offset shall
   * be a multiple of 4. For example, offset 8 means that the Counter will take
   * the low nibble of the byte 1, i.e. bits 8..11. */
  uint16 CRCOffset;
  /**< Bit offset of CRC (Least Significant Bit) from the beginning of the
   * Byte-Array (bit numbering: bit 0 is the least important). The offset shall
   * be a multiple of 8.
   * For example, offset 8 means that the CRC will take the byte 1, i.e.
   * bits 8..15. */
  uint16 DataID;
  /**< A unique identifier for protection against masquerading. */
  uint16 DataIDNibbleOffset;
  /**< Bit offset of the low nibble (Least Significant Bit) of the high byte of
   * Data ID from the beginning of the Byte-Array (bit numbering: bit 0 is the
   * least important). The offset shall be a multiple of 4. For example, offset
   * 8 means that the DataIDNibble
   * will take the low nibble of the byte 1, i.e. bits 8..11. */
  E2E_P01DataIDMode DataIDMode;
  /**< Inclusion mode of ID in CRC computation. */
  uint16 DataLength;
  /**< Length of the data in bits. The value shall be a multiple of 8 and shall
   * be <= 2048. */
  uint8 MaxDeltaCounterInit;
  /**< Initial maximum allowed gap between two counter values of two
   * consecutively received valid Data. */
  uint8 MaxNoNewOrRepeatedData;
  /**< Maximum amount of missing or repeated Data which the receiver does not
   * expect to exceed under normal communication conditions. */
  uint8 SyncCounterInit;
  /**< Number of Data required for validating the consistency of the counter
   * that must be received with a valid counter after the detection of an
   * unexpected behavior of a received counter. */
} E2E_P01ConfigType;

#define NULL_PTR ((void *)0)
#define E_NOT_OK 1U
#define E_OK 0U
/** brief Function completed successfully. */
#define E2E_E_OK 0U

#define E2E_E_INPUTERR_NULL 0x13U
#define E2E_E_INPUTERR_WRONG 0x17U
/** brief XOR value which is applied on the result before returned by the Crc
 * routine */
#define E2EP01_CRC_FINALXORVALUE 0xFFU
/** brief Xor-value for Crc calculation with polynomial 0x1D */
#define SCRC_CRC8_XORVALUE 0x00U
/** brief Initial value used for Crc calculation with polynomial 0x1D
 * (SAE-J1850) */
#define SCRC_CRC8_INITIALVALUE 0x00U
/** brief Start value for Crc calculation
 *
 * Note: The CalculateCRC8() API is XORing this start value with 0xFF
 * resulting with actual internal start value equal to 0x00.
 */
#define E2EP01_CRC_STARTVALUE 0xFFU

/** brief Maximum allowed data length for E2E Profile 01 in bits */
#define E2EP01_DATALENGTH_MAX 2048U
/** brief Minimum allowed data length for E2E Profile 01 in bits
 * shall be a multiple of 8 */
#define E2EP01_DATALENGTH_MIN 16U
/** brief Maximum allowed counter value for E2E Profile 01 */
#define E2EP01_COUNTER_MAX 14U

/** brief In case the macro is not generated by the E2EXf MCG it
 * must be initialized with the default value*/
#define E2EXF_WAIT_FOR_FIRST_DATA_INIT_VALUE FALSE

/** brief Function completed successfully. */
#define E2E_E_OK 0U
/**
 * brief The checks of the Data in this cycle were successful (including
 * counter check).
 *
 * Note: related to E2E_PCheckStatusType
 */
#define E2E_P_OK 0x00U
/**
 * brief Error not related to counters occurred (e.g. wrong crc, wrong length,
 * wrong DataID) or the return of the check function was not OK.
 *
 * Note: related to E2E_PCheckStatusType
 */
#define E2E_P_ERROR 0x03U
/**
 * brief Either no new data is available, or the new data has a repeated
 * counter.
 *
 * Note: related to E2E_PCheckStatusType
 */
#define E2E_P_REPEATED 0x01U
/**
 * brief No new Data is available since the last call of the check function.
 *
 * Note: related to E2E_PCheckStatusType
 */
#define E2E_P_NONEWDATA 0x05U
/**
 * brief The checks of the Data in this cycle were successful, with the
 * exception of counter jump, which changed more than allowed delta.
 *
 * Note: related to E2E_PCheckStatusType
 */
#define E2E_P_WRONGSEQUENCE 0x02U

#define CONST(consttype, memclass) consttype const
#define FUNC(rettype, memclass) rettype
#define P2CONST(ptrtype, memclass, ptrclass) const ptrtype *
#define P2VAR(ptrtype, memclass, ptrclass) ptrtype *

FUNC(Std_ReturnType, E2E_CODE)
E2E_P01Protect(P2CONST(E2E_P01ConfigType, AUTOMATIC, E2E_APPL_CONST) Config,
               P2VAR(E2E_P01ProtectStateType, AUTOMATIC, E2E_APPL_DATA) State,
               P2VAR(uint8, AUTOMATIC, E2E_APPL_DATA) Data);
FUNC(Std_ReturnType, E2E_CODE)
E2E_P01ProtectInit(P2VAR(E2E_P01ProtectStateType, AUTOMATIC, E2E_APPL_DATA)
                       StatePtr);
FUNC(Std_ReturnType, E2E_CODE)
E2E_P01Check(P2CONST(E2E_P01ConfigType, AUTOMATIC, E2E_APPL_CONST) Config,
             P2VAR(E2E_P01CheckStateType, AUTOMATIC, E2E_APPL_DATA) State,
             P2CONST(uint8, AUTOMATIC, E2E_APPL_DATA) Data);
FUNC(Std_ReturnType, E2E_CODE)
E2E_P01CheckInit(P2VAR(E2E_P01CheckStateType, AUTOMATIC, E2E_APPL_DATA)
                     StatePtr);
FUNC(E2E_PCheckStatusType, E2E_CODE)
E2E_P01MapStatusToSM(Std_ReturnType CheckReturn, E2E_P01CheckStatusType Status,
                     boolean profileBehavior);

/**
 * brief Non-modifiable configuration of the data element sent over an RTE
 * port, for E2E Profile.
 *
 * The position of the counter and CRC is not configurable in Profile 2.
 */
typedef struct {
  uint16 DataLength;
  /**< Length of the data in bits. The value shall be a multiple of 8 and shall
   * be <= 2048. */
  uint8 DataIDList[16];
  /**< An array of appropriately chosen Data IDs for protection against
   * masquerading. */
  uint8 MaxDeltaCounterInit;
  /**< Initial maximum allowed gap between two counter values of two
   * consecutively received valid Data. */
  uint8 MaxNoNewOrRepeatedData;
  /**< Maximum amount of missing or repeated Data which the receiver does not
   * expect to exceed under normal communication conditions. */
  uint8 SyncCounterInit;
  /**< Number of Data required for validating the consistency of the counter
   * that must be received with a valid counter after the detection of an
   * unexpected behavior of a received counter. */
  uint16 Offset;
  /**< Offset of the E2E header in the Data[] array in bits.
   * It shall be 0 ≤ Offset ≤ MaxDataLength-(2*8) Since there is limitation for
   * this A4.2.1. It shall be configured as Zero always.*/
} E2E_P02ConfigType;
/**
 * brief State of the sender for a Data protected with E2E Profile 2.
 */
typedef struct {
  uint8 Counter;
  /**< Counter to be used for protecting the Data. The counter is incremented
   * modulo 16 */
} E2E_P02SenderStateType;
/**
 * brief Definition of E2E Profile 2 protect state type.
 *
 * Type-definition for backward-compatibility due to type renaming done in
 * AUTOSAR version 4.2.1.
 *
 */
typedef E2E_P02SenderStateType E2E_P02ProtectStateType;

/**
 * brief Definition of E2E Profile 2 receiver status type.
 *
 * Result of the verification of the Data in E2E Profile 2, determined by the
 * Check function.
 */
typedef enum {
  E2E_P02STATUS_OK = 0x0U,
  /**< New data has been correctly received. */
  E2E_P02STATUS_NONEWDATA = 0x1U,
  /**< The Check function has been invoked but new Data is not available since
     the last call. */
  E2E_P02STATUS_WRONGCRC = 0x2U,
  /**< The data has been received according to communication medium, but the CRC
     is incorrect. */
  E2E_P02STATUS_SYNC = 0x3U,
  /**< New data has been received after detection of an unexpected behavior of
     counter. */
  E2E_P02STATUS_INITIAL = 0x4U,
  /**< New data has been correctly received, but this is the first Data since
   * the receiver's (re-)initialization. */
  E2E_P02STATUS_REPEATED = 0x8U,
  /**< New data has been correctly received, but the Counter is identical
   * to the most recent Data */
  /**< received with Status _INITIAL, _OK, or _OKSOMELOST. */
  E2E_P02STATUS_OKSOMELOST = 0x20U,
  /**< New data has been correctly received, but some data in the sequence
   * have been probably lost. */
  E2E_P02STATUS_WRONGSEQUENCE = 0x40U
  /**< The new data has been correctly received, but the Counter Delta is too
   * big (DeltaCounter > MaxDeltaCounter) */
} E2E_P02ReceiverStatusType;
/**
 * brief Definition of E2E Profile 2 receiver state type.
 * State of the sender for a Data protected with E2E Profile 2.
 */
typedef struct {
  E2E_P02ReceiverStatusType Status;
  /**< Result of the verification of the Data, determined by the Check function.
   */
  uint8 LastValidCounter;
  /**< Counter of last valid received message. */
  uint8 MaxDeltaCounter;
  /**< MaxDeltaCounter specifies the maximum allowed difference between two
   * counter values of */
  /**< consecutively received valid messages. */
  boolean WaitForFirstData;
  /**< If true means that no correct data (with correct Data ID and CRC) has
   * been yet received */
  /**< after the receiver (re-)initialization. */
  boolean NewDataAvailable;
  /**< Indicates to E2E Library that a new data is available for the Library to
   * be checked. */
  /**< This attribute is set by the E2E Library caller and not by the E2E
   * Library. */
  uint8 LostData;
  /**< Number of data (messages) lost since reception of last valid one. */
  uint8 NoNewOrRepeatedDataCounter;
  /**< Amount of consecutive reception cycles in which either (1) there was no
   * new data, or (2) when the data was repeated. */
  uint8 SyncCounter;
  /**< Number of consecutively received valid Data required for determining the
   * consistency of the counter. */
} E2E_P02ReceiverStateType;
/**
 * brief Definition of E2E Profile 2 check state type.
 * Type-definition for backward-compatibility due to type renaming done in
 * AUTOSAR version 4.2.1.
 */
typedef E2E_P02ReceiverStateType E2E_P02CheckStateType;
typedef E2E_P02ReceiverStatusType E2E_P02CheckStatusType;
/** brief Maximum allowed counter value for E2E Profile 02 */
#define E2EP02_COUNTER_MAX 15U
/** brief Start value for Crc calculation */
#define E2EP02_CRC_STARTVALUE 0xFFU
/** brief Xor-value for Crc calculation with polynomial 0x12F */
#define SCRC_CRC8H2F_XORVALUE 0xFFU
/** brief Initial value used for Crc calculation with polynomial 0x12F */
#define SCRC_CRC8H2F_INITIALVALUE 0xFFU

/** brief Maximum allowed data length for E2E Profile 02 in bits */
#define E2EP02_DATALENGTH_MAX 2048U
/** brief Minimum allowed data length for E2E Profile 02 in bits
 * shall be a multiple of 8 */
#define E2EP02_DATALENGTH_MIN 16U

FUNC(Std_ReturnType, E2E_CODE)
E2E_P02Protect(P2CONST(E2E_P02ConfigType, AUTOMATIC, E2E_APPL_CONST) ConfigPtr,
               P2VAR(E2E_P02ProtectStateType, AUTOMATIC, E2E_APPL_DATA)
                   StatePtr,
               P2VAR(uint8, AUTOMATIC, E2E_APPL_DATA) DataPtr);
FUNC(Std_ReturnType, E2E_CODE)
E2E_P02ProtectInit(P2VAR(E2E_P02ProtectStateType, AUTOMATIC, E2E_APPL_DATA)
                       StatePtr);
FUNC(Std_ReturnType, E2E_CODE)
E2E_P02Check(P2CONST(E2E_P02ConfigType, AUTOMATIC, E2E_APPL_CONST) ConfigPtr,
             P2VAR(E2E_P02CheckStateType, AUTOMATIC, E2E_APPL_DATA) StatePtr,
             P2CONST(uint8, AUTOMATIC, E2E_APPL_DATA) DataPtr);
FUNC(Std_ReturnType, E2E_CODE)
E2E_P02CheckInit(P2VAR(E2E_P02CheckStateType, AUTOMATIC, E2E_APPL_DATA)
                     StatePtr);
FUNC(E2E_PCheckStatusType, E2E_CODE)
E2E_P02MapStatusToSM(Std_ReturnType CheckReturn, E2E_P02CheckStatusType Status,
                     boolean profileBehavior);

/**
 * brief Non-modifiable configuration of the data element sent over an RTE
 * port, for E2E Profile.
 * The position of the counter and CRC is not configurable in Profile 4.
 */
typedef struct {
  uint32 DataID;
  /**< A system-unique identifier of the Data. */
  uint16 Offset;
  /**< Bit offset of the E2E header from the beginning of the Data Array.
   *  The offset shall be a multiple of 8 and 0<=Offset<=MaxDataLength-(12*8).
   *  Example: If Offset equals 8, then the high byte of the E2E Length (16 bit)
   * is written to Byte 1, the low Byte is written to Byte 2. Additionally,
   * Offset + size of header (96 bits) shall be <= Length*8 */
  uint16 MinDataLength;
  /**< Minimum length of Data in bits. The value shall be ≤ 4096*8 (4kB) and
   * shall be ≥ 12*8 */
  uint16 MaxDataLength;
  /**< Maximum length of data in bits.
   * The value shall be a multiple of 8 and >= MinDataLength and <= 4096*8 (4kB)
   */
  uint16 MaxDeltaCounter;
  /**< Maximum allowed gap between two counter values of two consecutively
   * received valid Data. */
} E2E_P04ConfigType;
/**
 * brief State of the sender for a Data protected with E2E Profile 4.
 */
typedef struct {
  uint16 Counter;
  /**< Counter to be used for protecting the Data. */
} E2E_P04ProtectStateType;
/** brief E2E Profile 04 header size in bits. */
#define E2EP04_EB_E2EHEADER_SIZE_BITS 96U
/** brief Offset in bytes within the E2E header where MSB of Length coded. */
#define E2EP04_EB_E2EHEADER_LENGTH_OFFSET 0U
/** brief Offset in bytes within the E2E header where MSB of Counter coded. */
#define E2EP04_EB_E2EHEADER_COUNTER_OFFSET 2U
/** brief Offset in bytes within the E2E header where MSB of DataID coded. */
#define E2EP04_EB_E2EHEADER_DATAID_OFFSET 4U
/** brief Offset in bytes within the E2E header where MSB of CRC coded. */
#define E2EP04_EB_E2EHEADER_CRC_OFFSET 8U

/** brief Write a 2-byte value in Big Endian order to the passed Data Pointer
 */
#define E2EP04_EB_WRITE2BYTE_VALUE(DataPtr, Value)                             \
  do {                                                                         \
    (DataPtr)[0] = (uint8)((uint16)((Value) >> 8U) & (uint8)0xFFU);            \
    (DataPtr)[1] = (uint8)((Value) & (uint8)0xFFU);                            \
  } while (0)
/** brief Write a 4-byte value in Big Endian order to the passed Data Pointer
 */
#define E2EP04_EB_WRITE4BYTE_VALUE(DataPtr, Value)                             \
  do {                                                                         \
    (DataPtr)[0] = (uint8)((uint32)((Value) >> 24U) & (uint8)0xFFU);           \
    (DataPtr)[1] = (uint8)((uint32)((Value) >> 16U) & (uint8)0xFFU);           \
    (DataPtr)[2] = (uint8)((uint32)((Value) >> 8U) & (uint8)0xFFU);            \
    (DataPtr)[3] = (uint8)((Value) & (uint8)0xFFU);                            \
  } while (0)

/** brief Start value for Crc calculation */
#define E2EP04_EB_CRC_STARTVALUE (uint32)0xFFFFFFFFUL
/** brief Crc size in bytes within E2E header. */
#define E2EP04_EB_E2EHEADER_CRC_SIZE 4U
/** brief Xor-value for Crc calculation with polynomial 0x1F4ACFB13 */
#define SCRC_CRC32P4_XORVALUE 0xFFFFFFFFU
/** brief Initial value used for Crc calculation with polynomial 0x1F4ACFB13 */
#define SCRC_CRC32P4_INITIALVALUE 0xFFFFFFFFU
/** brief Maximum value for state counter */
#define E2EP04_EB_COUNTER_MAXVALUE 0xFFFFU

/**
 * brief Definition of E2E Profile 4 receiver status type.
 *
 * Result of the verification of the Data in E2E Profile 4, determined by the
 * Check function.
 */
typedef enum {
  E2E_P04STATUS_OK = 0x0U,
  /**< New data has been correctly received. */
  E2E_P04STATUS_NONEWDATA = 0x1U,
  /**< The Check function has been invoked but new Data is not available since
     the last call. */
  E2E_P04STATUS_ERROR = 0x2U,
  /**< The data has been received according to communication medium, but the CRC
     is incorrect. */
  E2E_P04STATUS_REPEATED = 0x8U,
  /**< New data has been correctly received, but the Counter is identical
   * to the most recent Data */
  E2E_P04STATUS_OKSOMELOST = 0x20U,
  /**< New data has been correctly received, but some data in the sequence
   * have been probably lost. */
  E2E_P04STATUS_WRONGSEQUENCE = 0x40U
  /**< The new data has been correctly received, but the Counter Delta is too
   * big (DeltaCounter > MaxDeltaCounter) */
} E2E_P04CheckStatusType;
/**
 * brief Definition of E2E Profile 4 receiver state type.
 * State of the sender for a Data protected with E2E Profile 4.
 */
typedef struct {
  E2E_P04CheckStatusType Status;
  /**< Result of the verification of the Data, determined by the Check function.
   */
  uint16 Counter;
  /**< Counter of last valid received message. */
} E2E_P04CheckStateType;
/** brief Read a 2-byte value in Big Endian order from the passed Data Pointer
 */
#define E2EP04_EB_READ2BYTE_VALUE(DataPtr)                                     \
  ((uint16)(((uint16)((DataPtr)[1])) |                                         \
            ((uint16)(((uint16)((DataPtr)[0])) << 8U))))
/** brief Read a 4-byte value in Big Endian order from the passed Data Pointer
 */
#define E2EP04_EB_READ4BYTE_VALUE(DataPtr)                                     \
  ((uint32)(((uint32)((DataPtr)[3])) |                                         \
            (uint32)(((uint32)(((uint32)((DataPtr)[2])) << 8U)) |              \
                     (uint32)(((uint32)(((uint32)((DataPtr)[1])) << 16U)) |    \
                              ((uint32)(((uint32)((DataPtr)[0])) << 24U))))))

FUNC(Std_ReturnType, E2E_CODE)
E2E_P04Protect(P2CONST(E2E_P04ConfigType, AUTOMATIC, E2E_APPL_CONST) ConfigPtr,
               P2VAR(E2E_P04ProtectStateType, AUTOMATIC, E2E_APPL_DATA)
                   StatePtr,
               P2VAR(uint8, AUTOMATIC, E2E_APPL_DATA) DataPtr, uint16 Length);
FUNC(Std_ReturnType, E2E_CODE)
E2E_P04ProtectInit(P2VAR(E2E_P04ProtectStateType, AUTOMATIC, E2E_APPL_DATA)
                       StatePtr);
FUNC(Std_ReturnType, E2E_CODE)
E2E_P04Check(P2CONST(E2E_P04ConfigType, AUTOMATIC, E2E_APPL_CONST) ConfigPtr,
             P2VAR(E2E_P04CheckStateType, AUTOMATIC, E2E_APPL_DATA) StatePtr,
             P2CONST(uint8, AUTOMATIC, E2E_APPL_DATA) DataPtr, uint16 Length);
FUNC(Std_ReturnType, E2E_CODE)
E2E_P04CheckInit(P2VAR(E2E_P04CheckStateType, AUTOMATIC, E2E_APPL_DATA)
                     StatePtr);
FUNC(E2E_PCheckStatusType, E2E_CODE)
E2E_P04MapStatusToSM(Std_ReturnType CheckReturn, E2E_P04CheckStatusType Status);

/**
 * brief Non-modifiable configuration of the data element sent over an RTE
 * port, for E2E Profile.
 * The position of the counter and CRC is not configurable in Profile 5.
 */
typedef struct {
  uint16 Offset;
  /**< Bit offset of the E2E header from the beginning of the Data Array.
   *  The offset shall be a multiple of 8 and 0<=Offset<=DataLength-(3*8).
   *  Example: If Offset equals 8, then the low byte of the E2E Crc (16 bit) is
   *  written to Byte 1, the high Byte is written to Byte 2. */
  uint16 DataLength;
  /**< Length of data in bits.
   * The value shall be a multiple of 8 and shall be ≥ 3*8 and ≤ 4096*8 (4kB).
   */
  uint16 DataID;
  /**< A system-unique identifier of the Data. */
  uint8 MaxDeltaCounter;
  /**< Maximum allowed gap between two counter values of two consecutively
   * received valid Data. */
} E2E_P05ConfigType;
/**
 * brief State of the sender for a Data protected with E2E Profile 5.
 */
typedef struct {
  uint8 Counter;
  /**< Counter to be used for protecting the Data. */
} E2E_P05ProtectStateType;
/** brief Start value for Crc calculation */
#define E2EP05_EB_CRC_STARTVALUE 0xFFFFU
/** brief Crc size in bytes within E2E header. */
#define E2EP05_EB_E2EHEADER_CRC_SIZE 2U
/** brief E2E Profile 05 header size in bits. */
#define E2EP05_EB_E2EHEADER_SIZE_BITS 24U
/** brief Offset in bytes within E2E header where least significant byte of
 * Counter is coded */
#define E2EP05_EB_E2EHEADER_COUNTER_OFFSET 2U
/** brief Offset in bytes within E2E header where least significant byte of CRC
 * is coded */
#define E2EP05_EB_E2EHEADER_CRC_OFFSET 0U
/** brief Write a 2-byte value in Little Endian order to the passed Data
 * Pointer */
#define E2EP05_EB_WRITE2BYTE_VALUE(DataPtr, Value)                             \
  do {                                                                         \
    (DataPtr)[0] = (uint8)((Value) & (uint8)0xFFU);                            \
    (DataPtr)[1] = (uint8)((uint16)((Value) >> 8U) & (uint8)0xFFU);            \
  } while (0)

/** brief Initial value used for Crc calculation with polynomial 0x11021 */
#define SCRC_CRC16_INITIALVALUE 0xFFFFU

/**
 * brief Definition of E2E Profile 5 receiver status type.
 *
 * Result of the verification of the Data in E2E Profile 5, determined by the
 * Check function.
 */
typedef enum {
  E2E_P05STATUS_OK = 0x00U,
  /**< New data has been correctly received. */
  E2E_P05STATUS_NONEWDATA = 0x01U,
  /**< The Check function has been invoked but new Data is not available since
     the last call. */
  E2E_P05STATUS_ERROR = 0x07U,
  /**< The data has been received according to communication medium, but the CRC
     is incorrect. */
  E2E_P05STATUS_REPEATED = 0x08U,
  /**< New data has been correctly received, but the Counter is identical
   * to the most recent Data */
  /**< received with Status _INITIAL, _OK, or _OKSOMELOST. */
  E2E_P05STATUS_OKSOMELOST = 0x20U,
  /**< New data has been correctly received, but some data in the sequence
   * have been probably lost. */
  E2E_P05STATUS_WRONGSEQUENCE = 0x40U
  /**< The new data has been correctly received, but the Counter Delta is too
   * big (DeltaCounter > MaxDeltaCounter) */
} E2E_P05CheckStatusType;

/**
 * brief Definition of E2E Profile 5 receiver state type.
 * State of the sender for a Data protected with E2E Profile 5.
 */
typedef struct {
  E2E_P05CheckStatusType Status;
  /**< Result of the verification of the Data, determined by the Check function.
   */
  uint8 Counter;
  /**< Counter of last valid received message. */
} E2E_P05CheckStateType;
/** brief Maximum value for state counter */
#define E2EP05_EB_COUNTER_MAXVALUE 0xFFU
/** brief Read a 2-byte value in Little Endian order from the passed Data
 * Pointer */
#define E2EP05_EB_READ2BYTE_VALUE(DataPtr)                                     \
  ((uint16)(((uint16)((DataPtr)[0])) |                                         \
            ((uint16)(((uint16)((DataPtr)[1])) << 8U))))

FUNC(Std_ReturnType, E2E_CODE)
E2E_P05Protect(P2CONST(E2E_P05ConfigType, AUTOMATIC, E2E_APPL_CONST) ConfigPtr,
               P2VAR(E2E_P05ProtectStateType, AUTOMATIC, E2E_APPL_DATA)
                   StatePtr,
               P2VAR(uint8, AUTOMATIC, E2E_APPL_DATA) DataPtr, uint16 Length);
FUNC(Std_ReturnType, E2E_CODE)
E2E_P05ProtectInit(P2VAR(E2E_P05ProtectStateType, AUTOMATIC, E2E_APPL_DATA)
                       StatePtr);
FUNC(Std_ReturnType, E2E_CODE)
E2E_P05Check(P2CONST(E2E_P05ConfigType, AUTOMATIC, E2E_APPL_CONST) ConfigPtr,
             P2VAR(E2E_P05CheckStateType, AUTOMATIC, E2E_APPL_DATA) StatePtr,
             P2CONST(uint8, AUTOMATIC, E2E_APPL_DATA) DataPtr, uint16 Length);
FUNC(Std_ReturnType, E2E_CODE)
E2E_P05CheckInit(P2VAR(E2E_P05CheckStateType, AUTOMATIC, E2E_APPL_DATA)
                     StatePtr);
FUNC(E2E_PCheckStatusType, E2E_CODE)
E2E_P05MapStatusToSM(Std_ReturnType CheckReturn, E2E_P05CheckStatusType Status);

/**
 * brief Non-modifiable configuration of the data element sent over an RTE
 * port, for E2E Profile.
 * The position of the counter and CRC is not configurable in Profile 6.
 */
typedef struct {
  uint16 Offset;
  /**< Bit offset of the E2E header from the beginning of the Data Array.
   *  The offset shall be a multiple of 8 and 0<=Offset<=MaxDataLength-(5*8).
   *  Example: If Offset equals 8, then the high byte of the E2E Crc (16 bit) is
   *  written to Byte 1, the low Byte is written to Byte 2.
   *  Additionally, Offset + size of header (40 bits) shall be <= Length*8 */
  uint16 MinDataLength;
  /**< Minimum length of Data in bits. The value shall be a multiple of 8 and >=
  5*8 and ≤ 4096*8 (4kB). */
  uint16 MaxDataLength;
  /**< Maximum length of data in bits.
   * The value shall be a multiple of 8 and >= MinDataLength and <= 4096*8
   * (4kB).*/
  uint16 DataID;
  /**< A system-unique identifier of the Data. */
  uint8 MaxDeltaCounter;
  /**< Maximum allowed gap between two counter values of two consecutively
   * received valid Data. */
} E2E_P06ConfigType;
/**
 * brief State of the sender for a Data protected with E2E Profile 6.
 */
typedef struct {
  uint8 Counter;
  /**< Counter to be used for protecting the Data. */
} E2E_P06ProtectStateType;
/**
 * brief Definition of E2E Profile 6 receiver status type.
 * Result of the verification of the Data in E2E Profile 6, determined by the
 * Check function.
 */
typedef enum {
  E2E_P06STATUS_OK = 0x00U,
  /**< New data has been correctly received. */
  E2E_P06STATUS_NONEWDATA = 0x01U,
  /**< The Check function has been invoked but new Data is not available since
     the last call. */
  E2E_P06STATUS_ERROR = 0x07U,
  /**< The data has been received according to communication medium, but the CRC
     is incorrect. */
  E2E_P06STATUS_REPEATED = 0x08U,
  /**< New data has been correctly received, but the Counter is identical
   * to the most recent Data */
  /**< received with Status _INITIAL, _OK, or _OKSOMELOST. */
  E2E_P06STATUS_OKSOMELOST = 0x20U,
  /**< New data has been correctly received, but some data in the sequence
   * have been probably lost. */
  E2E_P06STATUS_WRONGSEQUENCE = 0x40U
  /**< The new data has been correctly received, but the Counter Delta is too
   * big (DeltaCounter > MaxDeltaCounter) */
} E2E_P06CheckStatusType;

/**
 * brief Definition of E2E Profile 6 receiver state type.
 * State of the sender for a Data protected with E2E Profile 6.
 */
typedef struct {
  E2E_P06CheckStatusType Status;
  /**< Result of the verification of the Data, determined by the Check function.
   */
  uint8 Counter;
  /**< Counter of last valid received message. */
} E2E_P06CheckStateType;

/** brief E2E Profile 06 header size in bits. */
#define E2EP06_EB_E2EHEADER_SIZE_BITS 40U
/** brief Offset in bytes within E2E header where most significant byte of
 * Length is coded */
#define E2EP06_EB_E2EHEADER_LENGTH_OFFSET 2U
/** brief Offset in bytes within E2E header where most significant byte of
 * Counter is coded */
#define E2EP06_EB_E2EHEADER_COUNTER_OFFSET 4U
/** brief Offset in bytes within E2E header where most significant byte of CRC
 * is coded */
#define E2EP06_EB_E2EHEADER_CRC_OFFSET 0U
/** brief Write a 2-byte value in Big Endian order to the passed Data Pointer
 */
/** brief Start value for Crc calculation */
#define E2EP06_EB_CRC_STARTVALUE 0xFFFFU
/** brief Crc size in bytes within E2E header. */
#define E2EP06_EB_E2EHEADER_CRC_SIZE 2U
/** brief Maximum value for state counter */
#define E2EP06_EB_COUNTER_MAXVALUE 0xFFU

#define E2EP06_EB_WRITE2BYTE_VALUE(DataPtr, Value)                             \
  do {                                                                         \
    (DataPtr)[0] = (uint8)((uint16)((Value) >> 8U) & (uint8)0xFFU);            \
    (DataPtr)[1] = (uint8)((Value) & (uint8)0xFFU);                            \
  } while (0)
/** brief Read a 2-byte value in Big Endian order from the passed Data Pointer
 */
#define E2EP06_EB_READ2BYTE_VALUE(DataPtr)                                     \
  ((uint16)(((uint16)((DataPtr)[1])) |                                         \
            ((uint16)(((uint16)((DataPtr)[0])) << 8U))))

FUNC(Std_ReturnType, E2E_CODE)
E2E_P06Protect(P2CONST(E2E_P06ConfigType, AUTOMATIC, E2E_APPL_CONST) ConfigPtr,
               P2VAR(E2E_P06ProtectStateType, AUTOMATIC, E2E_APPL_DATA)
                   StatePtr,
               P2VAR(uint8, AUTOMATIC, E2E_APPL_DATA) DataPtr, uint16 Length);
FUNC(Std_ReturnType, E2E_CODE)
E2E_P06ProtectInit(P2VAR(E2E_P06ProtectStateType, AUTOMATIC, E2E_APPL_DATA)
                       StatePtr);
FUNC(Std_ReturnType, E2E_CODE)
E2E_P06Check(P2CONST(E2E_P06ConfigType, AUTOMATIC, E2E_APPL_CONST) ConfigPtr,
             P2VAR(E2E_P06CheckStateType, AUTOMATIC, E2E_APPL_DATA) StatePtr,
             P2CONST(uint8, AUTOMATIC, E2E_APPL_DATA) DataPtr, uint16 Length);
FUNC(Std_ReturnType, E2E_CODE)
E2E_P06CheckInit(P2VAR(E2E_P06CheckStateType, AUTOMATIC, E2E_APPL_DATA)
                     StatePtr);
FUNC(E2E_PCheckStatusType, E2E_CODE)
E2E_P06MapStatusToSM(Std_ReturnType CheckReturn, E2E_P06CheckStatusType Status);

#define E2ESM_MAX_WINDOW_SIZE 8
/** brief At least one pointer parameter is a NULL pointer. */
#define E2E_E_INPUTERR_NULL 0x13U
/** brief At least one input parameter is erroneous (e.g. out of range) */
#define E2E_E_INPUTERR_WRONG 0x17U
/**
 * brief An internal library error has occurred.
 * An internal library error has occurred. (e.g. error detected by program flow
 * monitoring, violated invariant or postcondition)
 */
#define E2E_E_INTERR 0x19U
/** brief Function executed in wrong state. */
#define E2E_E_WRONGSTATE 0x1AU

#define E2E_SM_VALID 0U
#define E2E_SM_DEINIT 1U
#define E2E_SM_NODATA 2U
#define E2E_SM_INIT 3U
#define E2E_SM_INVALID 4U

#define E2E_P_NOTAVAILABLE 0x04U
/**
 * brief Definition of E2E State Machine communication channel configuration
 * type.
 * Configuration of a communication channel for exchanging Data.
 */
typedef struct {
  uint8 WindowSize;
  /**< Size of the monitoring window for the state machine. */
  uint8 MinOkStateInit;
  /**< Minimal number of checks in which ProfileStatus equal to E2E_P_OK was
   *   determined within the last WindowSize checks (for the state E2E_SM_INIT)
   *   required to change to state E2E_SM_VALID. */
  uint8 MaxErrorStateInit;
  /**< Maximal number of checks in which ProfileStatus equal to E2E_P_ERROR was
   *   determined within the last WindowSize checks (for the state E2E_SM_INIT).
   */
  uint8 MinOkStateValid;
  /**< Minimal number of checks in which ProfileStatus equal to E2E_P_OK was
   *   determined within the last WindowSize checks (for the state E2E_SM_VALID)
   *   required to keep in state E2E_SM_VALID. */
  uint8 MaxErrorStateValid;
  /**< Maximal number of checks in which ProfileStatus equal to E2E_P_ERROR was
   *   determined, within the last WindowSize checks (for the state
   * E2E_SM_VALID). */
  uint8 MinOkStateInvalid;
  /**< Minimum number of checks in which ProfileStatus equal to E2E_P_OK was
   *   determined within the last WindowSize checks (for the state
   * E2E_SM_INVALID) required to change to state E2E_SM_VALID. */
  uint8 MaxErrorStateInvalid;
  /**< Maximal number of checks in which ProfileStatus equal to E2E_P_ERROR was
   *   determined within the last WindowSize checks (for the state
   * E2E_SM_INVALID). */
} E2E_SMConfigType;

/**
 * brief Definition of E2E State Machine state type.
 * Status of the communication channel exchanging the data.
 * If the status is OK, then the data may be used.
 */
typedef uint8 E2E_SMStateType;

/**
 * brief Definition of E2E State Machine check state type.
 * State of the protection of a communication channel.
 */
typedef struct {
  uint8 ProfileStatusWindowArray[E2ESM_MAX_WINDOW_SIZE];
  /**< Array in which the ProfileStatus of the last
   *   E2E-checks are stored. The array size is fixed with
   * E2ESM_MAX_WINDOW_SIZE. */
  uint8 WindowTopIndex;
  /**< Index in the array at which the next ProfileStatus is to be written. */
  uint8 OkCount;
  /**< Count of checks in which ProfileStatus equal to E2E_P_OK was determined
   *   within the last WindowSize checks. */
  uint8 ErrorCount;
  /**< Count of checks in which ProfileStatus equal to E2E_P_ERROR was
   * determined within the last WindowSize checks. */
  E2E_SMStateType SMState;
  /**< The current state in the state machine. */
} E2E_SMCheckStateType;

FUNC(Std_ReturnType, E2E_CODE)
E2E_SMCheck(E2E_PCheckStatusType ProfileStatus,
            P2CONST(E2E_SMConfigType, AUTOMATIC, E2E_APPL_CONST) ConfigPtr,
            P2VAR(E2E_SMCheckStateType, AUTOMATIC, E2E_APPL_DATA) StatePtr);
FUNC(Std_ReturnType, E2E_CODE)
E2E_SMCheckInit(P2VAR(E2E_SMCheckStateType, AUTOMATIC, E2E_APPL_DATA) StatePtr,
                P2CONST(E2E_SMConfigType, AUTOMATIC, E2E_APPL_CONST) ConfigPtr);

#define CRC_CRC8_XOR_VALUE ((uint8)0x00U)

uint8 E2E_CRC8u8(uint8 E2E_Data, uint8 E2E_StartValue);
uint8 E2E_CRC8u16(uint16 E2E_Data, uint8 E2E_StartValue);
uint8 E2E_CRC8u32(uint32 E2E_Data, uint8 E2E_StartValue);

uint8 E2E_CRC8u8Array(const uint8 *E2E_DataPtr, uint32 E2E_ArrayLength,
                      uint8 E2E_StartValue);
uint8 E2E_CRC8u16Array(const uint16 *E2E_DataPtr, uint32 E2E_ArrayLength,
                       uint8 E2E_StartValue);
uint8 E2E_CRC8u32Array(const uint32 *E2E_DataPtr, uint32 E2E_ArrayLength,
                       uint8 E2E_StartValue);

uint8 E2E_CRC8H2Fu8(uint8 E2E_Data, uint8 E2E_StartValue);
uint8 E2E_CRC8H2Fu16(uint16 E2E_Data, uint8 E2E_StartValue);
uint8 E2E_CRC8H2Fu32(uint32 E2E_Data, uint8 E2E_StartValue);

uint8 E2E_CRC8H2Fu8Array(const uint8 *E2E_DataPtr, uint32 E2E_ArrayLength,
                         uint8 E2E_StartValue);
uint8 E2E_CRC8H2Fu16Array(const uint16 *E2E_DataPtr, uint32 E2E_ArrayLength,
                          uint8 E2E_StartValue);
uint8 E2E_CRC8H2Fu32Array(const uint32 *E2E_DataPtr, uint32 E2E_ArrayLength,
                          uint8 E2E_StartValue);

uint8 E2E_UpdateCounter(uint8 Counter);

#endif